package com.yystar.support.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.lang3.StringUtils;


import com.yystar.support.base.util.AppUtility;

public abstract class WDateUtility {

	public static final String DATE_TIME_DEFAULT_PARSE_PATTERN = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_DEFAULT_PARSE_PATTERN = "yyyy-MM-dd";
	public static final String COOKIE_TIMEZONE_KEY = "timezone";
	public static final String DEFAULT_TIME_ZONE = "GMT-4:00";

	public static Date initDate = null;
	static {
		initDate = parse("1900-01-01", DATE_DEFAULT_PARSE_PATTERN);
	}

	public static java.util.Date parse(String text) {
		return parse(text, "");
	}

	/**
	 * Get Date
	 * 
	 * @return
	 */
	public static java.util.Date getTodayDate() {
		java.util.Date result = null;
		SimpleDateFormat sdf2 = null;

		sdf2 = new SimpleDateFormat("yyyy-MM-dd");

		result = new java.util.Date();

		try {
			result = sdf2.parse(sdf2.format(result) + " 00:00:00");
		} catch (ParseException ex) {
			result = new java.util.Date();
		}

		return result;
	}

	public static java.util.Date parse(String text, String format) {
		java.util.Date result = null;

		SimpleDateFormat sdf = null;
		if (StringUtils.isEmpty(format)) {
			format = DATE_TIME_DEFAULT_PARSE_PATTERN;
		}
		sdf = new SimpleDateFormat(format);
		try {
			result = sdf.parse(text);
		} catch (ParseException ex) {
			result = new java.util.Date();
		}

		return result;
	}

	public static String formatDate(java.util.Date date) {
		String result;

		SimpleDateFormat sdf = null;
		sdf = new SimpleDateFormat(DATE_DEFAULT_PARSE_PATTERN);
		try {
			result = sdf.format(date);
		} catch (Exception ex) {
			result = "";
		}

		return result;
	}

	public static String formatDate(java.util.Date date, String parseFormat) {
		String result;

		SimpleDateFormat sdf = null;
		sdf = new SimpleDateFormat(parseFormat);
		try {
			result = sdf.format(date);
		} catch (Exception ex) {
			result = "";
		}

		return result;
	}

	public static boolean checkDateFormat(Date date) {
		String strDate = WTextUtility.formatDate(WTextUtility.getDateFormatter(DATE_TIME_DEFAULT_PARSE_PATTERN), date);
		String eL = "^(\\d{4})-(\\d{1,2})-(\\d{1,2}) (0\\d{1}|1\\d{1}|2[0-3]):[0-5]\\d{1}:([0-5]\\d{1})$";
		Pattern p = Pattern.compile(eL);
		Matcher m = p.matcher(strDate);
		return m.matches();
	}

	/**
	 * Add Day
	 * 
	 * @param date
	 * @param dayDiff
	 * @return
	 */
	public static java.util.Date dateAddDay(java.util.Date date, int dayDiff) {
		Calendar cal = null;

		cal = Calendar.getInstance();
		cal.setTime(date);

		cal.add(Calendar.DAY_OF_MONTH, dayDiff);

		return cal.getTime();
	}

	/**
	 * XmlCalendar Conversion Date
	 * 
	 * @param xmlCalendar
	 * @return
	 * @throws DatatypeConfigurationException
	 */
	public static java.util.Date convertXmlCalendarToDate(XMLGregorianCalendar xmlCalendar) {
		Date date = null;
		try {
			date = xmlCalendar.toGregorianCalendar().getTime();
		} catch (Exception e) {
			AppUtility.recordException(e);
		}

		return date;
	}

	/**
	 * Calendar Convert
	 * 
	 * @param date
	 * @return
	 * @throws DatatypeConfigurationException
	 */
	public static XMLGregorianCalendar convertToXmlCalendar(Date date) {
		XMLGregorianCalendar result = null;
		try {
			result = DatatypeFactory.newInstance().newXMLGregorianCalendar();
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(date);

			result.setYear(calendar.get(Calendar.YEAR));
			result.setMonth(calendar.get(Calendar.MONTH) + 1);
			result.setDay(calendar.get(Calendar.DAY_OF_MONTH));
			result.setHour(calendar.get(Calendar.HOUR_OF_DAY));
			result.setMinute(calendar.get(Calendar.MINUTE));
			result.setSecond(calendar.get(Calendar.SECOND));
			result.setMillisecond(calendar.get(Calendar.MILLISECOND));
			result.setTimezone(calendar.get(Calendar.ZONE_OFFSET) / 60000);
		} catch (DatatypeConfigurationException e) {
			AppUtility.recordException(e);
		}

		return result;
	}

	public static String formatDate(String timeZone, String pattern, Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
		return sdf.format(date);
	}
	
	public static String formatDate(HttpServletRequest request, String pattern, Date date) {
		String getTimeZoneId = getTimeZoneId(request);
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		sdf.setTimeZone(TimeZone.getTimeZone(getTimeZoneId));
		return sdf.format(date);
	}
	
	
	public static int getOffset(String timeZoneId) {
		return TimeZone.getTimeZone(timeZoneId).getRawOffset() - TimeZone.getTimeZone(DEFAULT_TIME_ZONE).getRawOffset();
	}
	
	public static java.util.Date getDefaultTimeZoneDate(HttpServletRequest request, java.util.Date date) {
		String timeZoneId = WDateUtility.getTimeZoneId(request);
		int offSet = WDateUtility.getOffset(timeZoneId);
		java.util.Date returDate = new java.util.Date(date.getTime() + offSet);
		return returDate;
	}
	
	public static java.util.Date getDefaultTimeZoneDate(String timeZoneId, java.util.Date date) {
		int offSet = WDateUtility.getOffset(timeZoneId);
		java.util.Date returDate = new java.util.Date(date.getTime() + offSet);
		return returDate;
	}
	
	public static String getTimeZoneId(HttpServletRequest request) {
		if (request == null)
			return DEFAULT_TIME_ZONE;
		Cookie cookie = CookieUtil.getCookie(request, COOKIE_TIMEZONE_KEY);
		String timeZoneId = cookie == null ? null : cookie.getValue();
		if (StringUtils.isBlank(timeZoneId)) {
			timeZoneId = DEFAULT_TIME_ZONE;
		}
		return timeZoneId;
	}
	
}
